#include "encoderAcc.h"
#include<cassert>
encoderAcc::encoderAcc(uint32_t samplin, uint32_t channel, uint32_t fmt) {
	m_sampling = samplin;
	m_channel = channel;
	m_fmt = fmt;
	
	m_frameSize = 0;
	m_audioCodecaac = NULL;
	m_audioCodecContex = NULL;
	assert(AV_SAMPLE_FMT_FLTP == fmt);
}
encoderAcc::~encoderAcc() {
	deleteaac();
}

uint32_t encoderAcc::getFrameSize() const {
	return m_frameSize;
}

int encoderAcc::deleteaac() {
	if (m_audioCodecContex) {
		avcodec_free_context(&m_audioCodecContex);
	}
	return 1;
}

int encoderAcc::initaac() {
	m_audioCodecaac = avcodec_find_encoder(AV_CODEC_ID_AAC);
	if (NULL == m_audioCodecaac) {
		LOG("encoderAcc::init264  avcodec_find_encoder  failing");
		return -1;
	}
	m_audioCodecContex = avcodec_alloc_context3(m_audioCodecaac);
	if (NULL == m_audioCodecContex) {
		LOG("encoderH264::init264  avcodec_alloc_context3  failing");
		return -1;
	}

	m_audioCodecContex->bit_rate = 64 * 1024;
	m_audioCodecContex->sample_rate = m_sampling;
	//av_get_channel_layout_nb_channels(m_audioCodecContex->channel_layout);
	m_audioCodecContex->channels =	m_channel; 
	//AV_CH_LAYOUT_STEREO
	m_audioCodecContex->channel_layout = av_get_default_channel_layout(m_channel);
	m_audioCodecContex->sample_fmt = (AVSampleFormat)m_fmt;
	//m_audioCodecContex->time_base = { 1,24 };

	if (0 != avcodec_open2(m_audioCodecContex, m_audioCodecaac, NULL)) {
		LOG("encoderAcc::init264  avcodec_open2  failing");
		return -1;
	}
	m_frameSize = av_samples_get_buffer_size(NULL, m_audioCodecContex->channels, m_audioCodecContex->sample_rate, m_audioCodecContex->sample_fmt, 0);
	if (0 == m_frameSize) {
		LOG("encoderAcc::init264  av_image_get_buffer_size  failing");
		return -1;
	}
	printf("%d ", m_audioCodecContex->frame_size);
	return 0;
}

uint64_t  encoderAcc::calctimeout(uint64_t pts, int64_t ffmpeg_time_base) {
	uint64_t newpts = av_rescale_q(pts, (AVRational)AVRational { 1, (int)ffmpeg_time_base}, m_audioCodecContex->time_base);
	return newpts;
}


int encoderAcc::encodec(AVFrame* fream, std::vector<AVPacket*>& listpkt) {
	char errorinfo[128];
	int ret = avcodec_send_frame(m_audioCodecContex, fream);
	if (ret < 0)
	{
		fream->sample_rate;
		fream->channels;
		fream->nb_samples;
		fream->format;
		fream->channel_layout;
		fprintf(stderr, "Error sending a frame for encoding\n");
		fprintf(stderr, "Error sending a frame for encoding\n");
		av_strerror(ret, errorinfo, 128);
		LOG(errorinfo);
		return -1;

	}
	int t_count = 0;
	while (ret >= 0) {
		AVPacket* pkt = av_packet_alloc();
		ret = avcodec_receive_packet(m_audioCodecContex, pkt);

		if (0 == ret) {
			printf("pts  %d  dts %d\n", pkt->pts, pkt->dts);
			listpkt.push_back(pkt);
			t_count++;
		}
		if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
			av_packet_free(&pkt);
			break;
		}
		else if (ret < 0) {
			av_packet_free(&pkt);
			fprintf(stderr, "Error encoding audio frame\n");
			break;
		}
	}
	return t_count;
}
